package aiball

import java.lang.reflect.Type;

import grails.plugin.mail.*;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.tools.ant.taskdefs.SendEmail;
import org.omg.CORBA.Current;
import org.springframework.dao.DataIntegrityViolationException

import components.GlobalConstants;
import grails.plugins.springsecurity.Secured


import sun.security.provider.MD5;

class UserAccountController {

	def springSecurityService

	static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

	def index() {
		if(springSecurityService.isLoggedIn()) {
			if(springSecurityService.getPrincipal().getAuthorities().toString().equals("[ROLE_ADMIN]")) {
				redirect(action: "list", params: params)
			}
			else {
				params.id = ((UserAccount) springSecurityService.getCurrentUser()).id
				redirect(action: "show", params: params)
			}
		}
		else {
			redirect(controller: "login", action: "auth", params: params)
		}
	}

	def list() {
		if(!springSecurityService.getPrincipal().getAuthorities().toString().equals("[ROLE_ADMIN]")) {
			redirect(action: "show", params: params)
		}
		params.max = Math.min(params.max ? params.int('max') : 10, 100) 
		[userAccountInstanceList: UserAccount.list(params), userAccountInstanceTotal: UserAccount.count(), springSecurityService: springSecurityService]
	}

	def create() {
		[userAccountInstance: new UserAccount(params)]
	}

	def save() {
		def userAccountInstance = new UserAccount(params)
		def p1=new Player(
				name: "Player1",
				sourceCode: GlobalConstants.TEST_PLAYER_JAVA
				).save(failOnError: true)
		def p2=new Player(
				name: "Player2",
				sourceCode: GlobalConstants.TEST_PLAYER_JAVA
				).save(failOnError: true)
		def p3=new Player(
				name: "Player3",
				sourceCode: GlobalConstants.TEST_PLAYER_JAVA
				).save(failOnError: true)
		def p4=new Player(
				name: "Player4",
				sourceCode: GlobalConstants.TEST_PLAYER_JAVA
				).save(failOnError: true)
		def p5=new Player(
				name: "Player5",
				sourceCode: GlobalConstants.TEST_PLAYER_JAVA
				).save(failOnError: true)
		def neuesTeam=new Team(
				name:"Team"+userAccountInstance.username,
				player1: p1,
				player2: p2,
				player3: p3,
				player4: p4,
				player5: p5,
				logoURL: "",
				description: "",
				warcry: "",
				model: 1
				).save(failOnError: true)

		def comp=new CompilerService();
		comp.compileAndParse(p1, GlobalConstants.TEST_PLAYER_JAVA);
		comp.generateLineupXML(comp.findTeamToPlayer(p1));


		userAccountInstance.setTeam(neuesTeam)
		userAccountInstance.setLastActivity(new Date())
		userAccountInstance.setEnabled(false)
		if (!userAccountInstance.save(flush: true)) {
			render(view: "create", model: [userAccountInstance: userAccountInstance])
			return
		}

		UserAccountUserRoles.create userAccountInstance, UserRoles.findByAuthority('ROLE_USER')

		String md5String = "irgendeinmuell" + userAccountInstance.password.toString();

		sendMail {
			to userAccountInstance.getEmail()
			from "no-reply@javakicker.de"
			subject "Email Verification"
			body  	"Hallo " + userAccountInstance.username + "!\n" +
					"Schoen, dass du bei JavaKicker mitmachen moechtest!\n" +
					"Um deinen Zugang zu bestaetigen, klicke bitte auf folgenden Link:\n\n" +
					GlobalConstants.URL_COMPLEATE + "/userAccount/verify?id=" + userAccountInstance.id + "&code=" + md5String.encodeAsMD5() + "\n\n" +
					"Danach kannst du dich dann mit deinen Daten einloggen und loslegen! Viel Spass!"
		}

		//noch eine Mail an mich
		sendMail {
			to "stefan@sayk.de"
			from "no-reply@javakicker.de"
			subject "neues JavaKicker Team"
			body  	"Neu auf JavaKicker: " + userAccountInstance.username + ", " + userAccountInstance.getEmail()
		}
		
		flash.message = message(code: 'default.created.message', args: [
			message(code: 'userAccount.label', default: 'UserAccount'),
			userAccountInstance.id
		])
		redirect(view: "gettingEmail")
	}

	//Bei Default Team Link zum erstellen eines neuen Teams sonst Name des Teams
	@Secured(['ROLE_USER', 'ROLE_ADMIN'])
	def show() {
		def userAccountInstance;

		if(!springSecurityService.getPrincipal().getAuthorities().toString().equals("[ROLE_ADMIN]")){
			userAccountInstance =((UserAccount) springSecurityService.getCurrentUser());
		}
		else{
			userAccountInstance=UserAccount.get(params.id);
		}
		if (!userAccountInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
			return
		}
		[userAccountInstance: userAccountInstance,springSecurityService: springSecurityService]
	}
	
	@Secured(['ROLE_USER', 'ROLE_ADMIN'])
	def edit() {
		def userAccountInstance;

		if(!springSecurityService.getPrincipal().getAuthorities().toString().equals("[ROLE_ADMIN]")){
			userAccountInstance =((UserAccount) springSecurityService.getCurrentUser());

		}
		else{
			userAccountInstance=UserAccount.get(params.id);
		}
		if (!userAccountInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
			return
		}

		[userAccountInstance: userAccountInstance]
	}
	
	@Secured(['ROLE_USER', 'ROLE_ADMIN'])
	def update() {
		def userAccountInstance = UserAccount.get(params.id)
		if (!userAccountInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
			return
		}

		if (params.version) {
			def version = params.version.toLong()
			if (userAccountInstance.version > version) {
				userAccountInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
						[
							message(code: 'userAccount.label', default: 'UserAccount')]
						as Object[],
						"Another user has updated this UserAccount while you were editing")
				render(view: "edit", model: [userAccountInstance: userAccountInstance])
				return
			}
		}

		userAccountInstance.properties = params

		if (!userAccountInstance.save(flush: true)) {
			render(view: "edit", model: [userAccountInstance: userAccountInstance])
			return
		}

		flash.message = message(code: 'default.updated.message', args: [
			message(code: 'userAccount.label', default: 'UserAccount'),
			userAccountInstance.id
		])
		redirect(action: "show", id: userAccountInstance.id)
	}
	
	
	@Secured(['ROLE_ADMIN'])
	def delete() {
		def userAccountInstance = UserAccount.get(params.id)
		if (!userAccountInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
			return
		}

		try {
			userAccountInstance.delete(flush: true)
			flash.message = message(code: 'default.deleted.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
		}
		catch (DataIntegrityViolationException e) {
			flash.message = message(code: 'default.not.deleted.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "show", id: params.id)
		}
	}

	def verify(){

		String md5String = "irgendeinmuell" + UserAccount.get(params.get('id')).password.toString();

		String encoded = md5String.encodeAsMD5();

		if ((UserAccount.get(params.get('id'))).enabled == true)
		{
			render(view: "verifyAlreadyVerified")
		}
		else if(md5String.encodeAsMD5() == params.get('code'))
		{
			render(view: "verifyTrue")
			UserAccount.get(params.get('id')).setEnabled(true);
			def maxsub=LeagueTeamPoints.executeQuery('select max(subLeague) from LeagueTeamPoints')[0];
			if(maxsub==null){
				maxsub=1;
			}
			def anzinmax=LeagueTeamPoints.findAllBySubLeague(maxsub).size();
			if(anzinmax<18){
				def addtlp=new LeagueTeamPoints(
						league: League.findById(1),
						subLeague: maxsub,
						team: UserAccount.get(params.get('id')).getTeam(),
						points:0
						).save(failOnError: true)
			}
			else{
				def addtlp=new LeagueTeamPoints(
						league: League.findById(1),
						subLeague: maxsub+1,
						team: UserAccount.get(params.get('id')).getTeam(),
						points:0
						).save(failOnError: true)
			}
		}
		else
		{
			render(view: "verifyFalse")
		}

	}

	def menuControlPanel()
	{
		def userAccountInstance = springSecurityService.getCurrentUser();
		if (!userAccountInstance) {
			render("---");
			return
		}
		[userAccountInstance: userAccountInstance]
	}

	def gettingEmail(){

	}

	@Secured(['ROLE_ADMIN'])
	def adminsection(){

	}
	
	@Secured(['ROLE_ADMIN'])
	def aktivate(){
		def userAccountInstance = UserAccount.get(params.id)
		if (!userAccountInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
			return
		}
		if (userAccountInstance.enabled == true)
		{
			render(view: "verifyAlreadyVerified")
		}
		else{
			flash.message = message(code: 'Der User '+userAccountInstance.username+' wurde Aktiviert')
			redirect(action: "list")
			userAccountInstance.setEnabled(true);
			def maxsub=LeagueTeamPoints.executeQuery('select max(subLeague) from LeagueTeamPoints')[0];
			if(maxsub==null){
				maxsub=1;
			}
			def anzinmax=LeagueTeamPoints.findAllBySubLeague(maxsub).size();
			if(anzinmax<18){
				def addtlp=new LeagueTeamPoints(
						league: League.findById(1),
						subLeague: maxsub,
						team: userAccountInstance.getTeam(),
						points:0
						).save(failOnError: true)
			}
			else{
				def addtlp=new LeagueTeamPoints(
						league: League.findById(1),
						subLeague: maxsub+1,
						team: userAccountInstance.getTeam(),
						points:0
						).save(failOnError: true)
			}
		}

	}
	@Secured(['ROLE_ADMIN'])
	def suspend(){
		def userAccountInstance = UserAccount.get(params.id)
		if (!userAccountInstance) {
			flash.message = message(code: 'default.not.found.message', args: [
				message(code: 'userAccount.label', default: 'UserAccount'),
				params.id
			])
			redirect(action: "list")
			return
		}

		if(userAccountInstance.enabled==false){
			flash.message = message(code: 'Der User '+userAccountInstance.username+' ist schon deaktiviert')
			redirect(action: "list")
		}
		else{
			int maxsub=LeagueTeamPoints.executeQuery("select max(subLeague) from LeagueTeamPoints")[0];
			int mysub=LeagueTeamPoints.findByLeagueAndTeam(League.get(1),userAccountInstance.getTeam()).subLeague;
			

			LeagueTeamPoints.findByLeagueAndTeam(League.get(1),userAccountInstance.getTeam()).delete();
			userAccountInstance.enabled=false;
			if(mysub!=maxsub){
				for(int i=mysub;i<maxsub;i++){
					def aufsteiger = LeagueTeamPoints.withCriteria{
						eq("subLeague", i+1)
						and {
							order('points', 'desc')
							order('goalDiff', 'desc')
						}
					}
					aufsteiger.get(0).subLeague=i;
					aufsteiger.get(0).points=0;
					aufsteiger.get(0).goalDiff=-99;
				}
			}
			flash.message = message(code: 'Der User '+userAccountInstance.username+' wurde deaktiviert und sein Team aus der Hauptliga entfernt')
			redirect(action: "list")

		}


	}

}
